{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# 散点图 (Scatter Plot) 教程\n",
        "\n",
        "本部分将详细讲解如何使用 Matplotlib 绘制散点图，包括基础散点图的绘制、散点图的定制选项以及高级散点图的应用。\n",
        "\n",
        "## 学习内容\n",
        "1. **基础散点图**\n",
        "   - `plt.scatter(x, y)` 绘制散点图\n",
        "   - 与 `plt.plot()` 的区别和使用场景\n",
        "\n",
        "2. **散点图定制**\n",
        "   - `s`：点的大小（可以是标量或数组）\n",
        "   - `c`：点的颜色（可以是标量、数组或颜色映射）\n",
        "   - `marker`：标记类型\n",
        "   - `alpha`：透明度\n",
        "   - `edgecolors`：边框颜色\n",
        "   - `cmap`：颜色映射（colormap）\n",
        "\n",
        "3. **高级散点图**\n",
        "   - 气泡图：使用 `s` 参数表示第三个维度\n",
        "   - 颜色映射散点图：使用 `c` 和 `cmap` 表示数值\n",
        "   - 多组散点图：不同颜色/标记区分不同组\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 导入必要的库\n",
        "import matplotlib.pyplot as plt\n",
        "import numpy as np\n",
        "\n",
        "# 设置中文字体（如果需要显示中文）\n",
        "plt.rcParams['font.sans-serif'] = ['PingFang SC', 'Arial Unicode MS']\n",
        "plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题\n",
        "\n",
        "# 在 Jupyter Notebook 中内联显示图形\n",
        "%matplotlib inline\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 第一部分：基础散点图\n",
        "\n",
        "散点图用于展示两个变量之间的关系，每个点代表一个数据点。散点图特别适合用于：\n",
        "- 观察两个变量之间的相关性\n",
        "- 识别数据中的模式和异常值\n",
        "- 展示数据的分布情况\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 1.1 plt.scatter(x, y) 绘制散点图\n",
        "\n",
        "`plt.scatter(x, y)` 是绘制散点图的基础函数，需要提供 x 轴和 y 轴的数据。\n",
        "\n",
        "**基本语法**：\n",
        "```python\n",
        "plt.scatter(x, y)\n",
        "```\n",
        "\n",
        "**参数说明**：\n",
        "- `x`：x 轴数据，可以是列表、数组等\n",
        "- `y`：y 轴数据，可以是列表、数组等\n",
        "- x 和 y 的长度必须相同\n",
        "\n",
        "**返回值**：\n",
        "- 返回一个 `PathCollection` 对象，可以用于后续的样式设置\n",
        "\n",
        "**与 plt.plot() 的区别**：\n",
        "- `plt.plot()` 主要用于绘制连续的线条，适合展示趋势\n",
        "- `plt.scatter()` 主要用于绘制独立的点，适合展示数据分布和关系\n",
        "- `plt.scatter()` 支持更灵活的点样式定制（大小、颜色等）\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例 1：基础散点图绘制\n",
        "# 生成随机数据\n",
        "np.random.seed(42)\n",
        "x = np.random.randn(100)  # 生成 100 个随机数\n",
        "y = np.random.randn(100)\n",
        "\n",
        "# 绘制散点图\n",
        "plt.figure(figsize=(8, 6))\n",
        "plt.scatter(x, y)\n",
        "plt.title('基础散点图示例', fontsize=14)\n",
        "plt.xlabel('x 轴', fontsize=12)\n",
        "plt.ylabel('y 轴', fontsize=12)\n",
        "plt.grid(True, alpha=0.3)\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 1.2 与 plt.plot() 的区别和使用场景\n",
        "\n",
        "虽然 `plt.plot()` 也可以绘制点，但 `plt.scatter()` 更适合散点图的应用场景。\n",
        "\n",
        "**主要区别**：\n",
        "\n",
        "1. **性能**：\n",
        "   - `plt.plot()` 对于大量点（>1000）性能更好\n",
        "   - `plt.scatter()` 对于少量点且需要不同样式时更灵活\n",
        "\n",
        "2. **样式定制**：\n",
        "   - `plt.plot()` 主要用于线条样式\n",
        "   - `plt.scatter()` 支持每个点不同的颜色和大小\n",
        "\n",
        "3. **使用场景**：\n",
        "   - `plt.plot()`：时间序列、函数图像、趋势线\n",
        "   - `plt.scatter()`：相关性分析、数据分布、分类数据\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例 2：plt.plot() vs plt.scatter() 对比\n",
        "x = np.linspace(0, 10, 50)\n",
        "y = np.sin(x) + np.random.randn(50) * 0.1\n",
        "\n",
        "fig, axes = plt.subplots(1, 2, figsize=(14, 5))\n",
        "\n",
        "# 使用 plt.plot() 绘制\n",
        "axes[0].plot(x, y, 'o', markersize=5)\n",
        "axes[0].set_title('使用 plt.plot() 绘制点', fontsize=12)\n",
        "axes[0].set_xlabel('x 轴', fontsize=10)\n",
        "axes[0].set_ylabel('y 轴', fontsize=10)\n",
        "axes[0].grid(True, alpha=0.3)\n",
        "\n",
        "# 使用 plt.scatter() 绘制\n",
        "axes[1].scatter(x, y, s=50)\n",
        "axes[1].set_title('使用 plt.scatter() 绘制点', fontsize=12)\n",
        "axes[1].set_xlabel('x 轴', fontsize=10)\n",
        "axes[1].set_ylabel('y 轴', fontsize=10)\n",
        "axes[1].grid(True, alpha=0.3)\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 第二部分：散点图定制\n",
        "\n",
        "散点图提供了丰富的定制选项，可以控制点的外观，使图表更加美观和信息丰富。\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.1 点的大小 (s 参数)\n",
        "\n",
        "`s` 参数用于控制点的大小，可以是：\n",
        "- **标量**：所有点使用相同大小\n",
        "- **数组**：每个点使用不同大小（用于气泡图）\n",
        "\n",
        "**基本语法**：\n",
        "```python\n",
        "plt.scatter(x, y, s=50)  # 标量，所有点大小相同\n",
        "plt.scatter(x, y, s=sizes)  # 数组，每个点大小不同\n",
        "```\n",
        "\n",
        "**注意事项**：\n",
        "- `s` 的单位是点的面积的平方（不是半径）\n",
        "- 默认值为 20\n",
        "- 数组长度必须与 x, y 相同\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例 3：不同大小的点\n",
        "np.random.seed(42)\n",
        "x = np.random.randn(50)\n",
        "y = np.random.randn(50)\n",
        "\n",
        "fig, axes = plt.subplots(1, 3, figsize=(15, 5))\n",
        "\n",
        "# 小点\n",
        "axes[0].scatter(x, y, s=20, alpha=0.6)\n",
        "axes[0].set_title('小点 (s=20)', fontsize=12)\n",
        "axes[0].grid(True, alpha=0.3)\n",
        "\n",
        "# 中等点\n",
        "axes[1].scatter(x, y, s=100, alpha=0.6)\n",
        "axes[1].set_title('中等点 (s=100)', fontsize=12)\n",
        "axes[1].grid(True, alpha=0.3)\n",
        "\n",
        "# 大点\n",
        "axes[2].scatter(x, y, s=300, alpha=0.6)\n",
        "axes[2].set_title('大点 (s=300)', fontsize=12)\n",
        "axes[2].grid(True, alpha=0.3)\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n",
        "\n",
        "# 示例 4：每个点不同大小（数组）\n",
        "np.random.seed(42)\n",
        "x = np.random.randn(50)\n",
        "y = np.random.randn(50)\n",
        "sizes = np.random.randint(20, 500, 50)  # 随机生成 50 个大小值\n",
        "\n",
        "plt.figure(figsize=(8, 6))\n",
        "plt.scatter(x, y, s=sizes, alpha=0.6)\n",
        "plt.title('每个点不同大小', fontsize=14)\n",
        "plt.xlabel('x 轴', fontsize=12)\n",
        "plt.ylabel('y 轴', fontsize=12)\n",
        "plt.grid(True, alpha=0.3)\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.2 点的颜色 (c 参数)\n",
        "\n",
        "`c` 参数用于控制点的颜色，可以是：\n",
        "- **标量**：所有点使用相同颜色（颜色名称或颜色代码）\n",
        "- **数组**：每个点使用不同颜色（需要配合 `cmap` 使用）\n",
        "\n",
        "**基本语法**：\n",
        "```python\n",
        "plt.scatter(x, y, c='red')  # 标量，所有点相同颜色\n",
        "plt.scatter(x, y, c=colors)  # 数组，每个点不同颜色\n",
        "plt.scatter(x, y, c=values, cmap='viridis')  # 数组 + 颜色映射\n",
        "```\n",
        "\n",
        "**颜色表示方法**：\n",
        "- 颜色名称：`'red'`, `'blue'`, `'green'` 等\n",
        "- 单字符：`'r'`, `'b'`, `'g'` 等\n",
        "- 十六进制：`'#FF5733'` 等\n",
        "- RGB 元组：`(0.1, 0.2, 0.5)` 等\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例 5：不同颜色表示方法\n",
        "np.random.seed(42)\n",
        "x = np.random.randn(50)\n",
        "y = np.random.randn(50)\n",
        "\n",
        "fig, axes = plt.subplots(2, 2, figsize=(12, 10))\n",
        "\n",
        "# 颜色名称\n",
        "axes[0, 0].scatter(x, y, c='red', s=100, alpha=0.6)\n",
        "axes[0, 0].set_title('颜色名称：red', fontsize=12)\n",
        "axes[0, 0].grid(True, alpha=0.3)\n",
        "\n",
        "# 单字符\n",
        "axes[0, 1].scatter(x, y, c='b', s=100, alpha=0.6)\n",
        "axes[0, 1].set_title('单字符：b (blue)', fontsize=12)\n",
        "axes[0, 1].grid(True, alpha=0.3)\n",
        "\n",
        "# 十六进制\n",
        "axes[1, 0].scatter(x, y, c='#FF5733', s=100, alpha=0.6)\n",
        "axes[1, 0].set_title('十六进制：#FF5733', fontsize=12)\n",
        "axes[1, 0].grid(True, alpha=0.3)\n",
        "\n",
        "# RGB 元组\n",
        "axes[1, 1].scatter(x, y, c=(0.2, 0.6, 0.3), s=100, alpha=0.6)\n",
        "axes[1, 1].set_title('RGB 元组：(0.2, 0.6, 0.3)', fontsize=12)\n",
        "axes[1, 1].grid(True, alpha=0.3)\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.3 标记类型 (marker 参数)\n",
        "\n",
        "`marker` 参数用于控制点的形状，与 `plt.plot()` 中的标记类型相同。\n",
        "\n",
        "**常用标记**：\n",
        "- `'o'`：圆圈（默认）\n",
        "- `'s'`：方形\n",
        "- `'^'`：向上三角形\n",
        "- `'v'`：向下三角形\n",
        "- `'*'`：星形\n",
        "- `'x'`：叉号\n",
        "- `'+'`：加号\n",
        "- `'D'`：菱形\n",
        "- `'p'`：五边形\n",
        "- `'h'`：六边形\n",
        "\n",
        "**基本语法**：\n",
        "```python\n",
        "plt.scatter(x, y, marker='o')  # 圆圈\n",
        "plt.scatter(x, y, marker='s')  # 方形\n",
        "plt.scatter(x, y, marker='*')  # 星形\n",
        "```\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例 6：不同标记类型\n",
        "np.random.seed(42)\n",
        "markers = ['o', 's', '^', 'v', '*', 'x', '+', 'D', 'p', 'h']\n",
        "marker_names = ['圆圈', '方形', '上三角', '下三角', '星形', '叉号', '加号', '菱形', '五边形', '六边形']\n",
        "\n",
        "fig, axes = plt.subplots(2, 5, figsize=(15, 6))\n",
        "axes = axes.flatten()\n",
        "\n",
        "for i, (marker, name) in enumerate(zip(markers, marker_names)):\n",
        "    x = np.random.randn(30)\n",
        "    y = np.random.randn(30)\n",
        "    axes[i].scatter(x, y, marker=marker, s=100, alpha=0.6)\n",
        "    axes[i].set_title(f'{name} ({marker})', fontsize=10)\n",
        "    axes[i].grid(True, alpha=0.3)\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.4 透明度 (alpha 参数)\n",
        "\n",
        "`alpha` 参数用于控制点的透明度，取值范围为 0（完全透明）到 1（完全不透明）。\n",
        "\n",
        "**基本语法**：\n",
        "```python\n",
        "plt.scatter(x, y, alpha=0.5)  # 50% 透明度\n",
        "```\n",
        "\n",
        "**使用场景**：\n",
        "- 当点重叠时，使用透明度可以看到重叠程度\n",
        "- 创建更美观的视觉效果\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例 7：不同透明度对比\n",
        "np.random.seed(42)\n",
        "x = np.random.randn(200)\n",
        "y = np.random.randn(200)\n",
        "\n",
        "fig, axes = plt.subplots(1, 3, figsize=(15, 5))\n",
        "\n",
        "# 不透明\n",
        "axes[0].scatter(x, y, alpha=1.0, s=50)\n",
        "axes[0].set_title('不透明 (alpha=1.0)', fontsize=12)\n",
        "axes[0].grid(True, alpha=0.3)\n",
        "\n",
        "# 半透明\n",
        "axes[1].scatter(x, y, alpha=0.5, s=50)\n",
        "axes[1].set_title('半透明 (alpha=0.5)', fontsize=12)\n",
        "axes[1].grid(True, alpha=0.3)\n",
        "\n",
        "# 高透明度\n",
        "axes[2].scatter(x, y, alpha=0.2, s=50)\n",
        "axes[2].set_title('高透明度 (alpha=0.2)', fontsize=12)\n",
        "axes[2].grid(True, alpha=0.3)\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.5 边框颜色 (edgecolors 参数)\n",
        "\n",
        "`edgecolors` 参数用于控制点的边框颜色。\n",
        "\n",
        "**基本语法**：\n",
        "```python\n",
        "plt.scatter(x, y, edgecolors='black')  # 黑色边框\n",
        "plt.scatter(x, y, edgecolors='none')   # 无边框\n",
        "plt.scatter(x, y, edgecolors='red', linewidths=2)  # 红色边框，线宽为2\n",
        "```\n",
        "\n",
        "**参数说明**：\n",
        "- `edgecolors`：边框颜色（可以是颜色名称、单字符、十六进制等）\n",
        "- `linewidths`：边框线宽（默认 1.5）\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例 8：边框颜色\n",
        "np.random.seed(42)\n",
        "x = np.random.randn(50)\n",
        "y = np.random.randn(50)\n",
        "\n",
        "fig, axes = plt.subplots(1, 3, figsize=(15, 5))\n",
        "\n",
        "# 无边框\n",
        "axes[0].scatter(x, y, c='blue', s=100, edgecolors='none', alpha=0.6)\n",
        "axes[0].set_title('无边框', fontsize=12)\n",
        "axes[0].grid(True, alpha=0.3)\n",
        "\n",
        "# 黑色边框\n",
        "axes[1].scatter(x, y, c='blue', s=100, edgecolors='black', alpha=0.6)\n",
        "axes[1].set_title('黑色边框', fontsize=12)\n",
        "axes[1].grid(True, alpha=0.3)\n",
        "\n",
        "# 红色边框，线宽为2\n",
        "axes[2].scatter(x, y, c='blue', s=100, edgecolors='red', linewidths=2, alpha=0.6)\n",
        "axes[2].set_title('红色边框，线宽为2', fontsize=12)\n",
        "axes[2].grid(True, alpha=0.3)\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.6 颜色映射 (cmap 参数)\n",
        "\n",
        "`cmap` 参数用于指定颜色映射，通常与 `c` 参数（数组）配合使用，将数值映射到颜色。\n",
        "\n",
        "**常用颜色映射**：\n",
        "- `'viridis'`：从紫色到黄色的渐变（默认，对色盲友好）\n",
        "- `'plasma'`：从紫色到粉色的渐变\n",
        "- `'inferno'`：从黑色到黄色的渐变\n",
        "- `'magma'`：从黑色到白色的渐变\n",
        "- `'coolwarm'`：从蓝色到红色的渐变\n",
        "- `'RdYlBu'`：从红色到黄色的渐变\n",
        "- `'jet'`：彩虹色（不推荐，对色盲不友好）\n",
        "\n",
        "**基本语法**：\n",
        "```python\n",
        "plt.scatter(x, y, c=values, cmap='viridis')\n",
        "plt.colorbar()  # 显示颜色条\n",
        "```\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例 9：颜色映射\n",
        "np.random.seed(42)\n",
        "x = np.random.randn(100)\n",
        "y = np.random.randn(100)\n",
        "values = np.random.randn(100)  # 第三个维度的值\n",
        "\n",
        "fig, axes = plt.subplots(2, 2, figsize=(12, 10))\n",
        "\n",
        "# viridis\n",
        "scatter1 = axes[0, 0].scatter(x, y, c=values, cmap='viridis', s=100, alpha=0.6)\n",
        "axes[0, 0].set_title('viridis 颜色映射', fontsize=12)\n",
        "axes[0, 0].grid(True, alpha=0.3)\n",
        "plt.colorbar(scatter1, ax=axes[0, 0])\n",
        "\n",
        "# plasma\n",
        "scatter2 = axes[0, 1].scatter(x, y, c=values, cmap='plasma', s=100, alpha=0.6)\n",
        "axes[0, 1].set_title('plasma 颜色映射', fontsize=12)\n",
        "axes[0, 1].grid(True, alpha=0.3)\n",
        "plt.colorbar(scatter2, ax=axes[0, 1])\n",
        "\n",
        "# coolwarm\n",
        "scatter3 = axes[1, 0].scatter(x, y, c=values, cmap='coolwarm', s=100, alpha=0.6)\n",
        "axes[1, 0].set_title('coolwarm 颜色映射', fontsize=12)\n",
        "axes[1, 0].grid(True, alpha=0.3)\n",
        "plt.colorbar(scatter3, ax=axes[1, 0])\n",
        "\n",
        "# RdYlBu\n",
        "scatter4 = axes[1, 1].scatter(x, y, c=values, cmap='RdYlBu', s=100, alpha=0.6)\n",
        "axes[1, 1].set_title('RdYlBu 颜色映射', fontsize=12)\n",
        "axes[1, 1].grid(True, alpha=0.3)\n",
        "plt.colorbar(scatter4, ax=axes[1, 1])\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 第三部分：高级散点图\n",
        "\n",
        "高级散点图利用多个参数组合，可以展示多维数据，使图表更加信息丰富。\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.1 气泡图\n",
        "\n",
        "气泡图是散点图的扩展，使用点的大小（`s` 参数）表示第三个维度的数据。\n",
        "\n",
        "**特点**：\n",
        "- x 轴：第一个变量\n",
        "- y 轴：第二个变量\n",
        "- 点的大小：第三个变量\n",
        "\n",
        "**基本语法**：\n",
        "```python\n",
        "plt.scatter(x, y, s=sizes, alpha=0.6)\n",
        "```\n",
        "\n",
        "**注意事项**：\n",
        "- `s` 的单位是面积的平方，所以如果要表示半径，需要平方\n",
        "- 使用 `alpha` 参数可以让重叠的点可见\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例 10：气泡图\n",
        "# 模拟销售数据：x=广告投入，y=销售额，s=利润\n",
        "np.random.seed(42)\n",
        "advertising = np.random.uniform(10, 100, 30)  # 广告投入（万元）\n",
        "sales = advertising * 2 + np.random.randn(30) * 20  # 销售额（万元）\n",
        "profit = np.random.uniform(5, 50, 30)  # 利润（万元）\n",
        "sizes = profit * 20  # 转换为点的大小\n",
        "\n",
        "plt.figure(figsize=(10, 6))\n",
        "plt.scatter(advertising, sales, s=sizes, alpha=0.6, c='steelblue', edgecolors='black', linewidths=1)\n",
        "plt.xlabel('广告投入（万元）', fontsize=12)\n",
        "plt.ylabel('销售额（万元）', fontsize=12)\n",
        "plt.title('气泡图：广告投入 vs 销售额（气泡大小表示利润）', fontsize=14)\n",
        "plt.grid(True, alpha=0.3)\n",
        "\n",
        "# 添加图例说明气泡大小\n",
        "for size in [10, 30, 50]:\n",
        "    plt.scatter([], [], s=size*20, c='steelblue', alpha=0.6, edgecolors='black', \n",
        "                label=f'利润 {size} 万元')\n",
        "plt.legend(scatterpoints=1, frameon=True, labelspacing=1, title='利润', fontsize=10)\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.2 颜色映射散点图\n",
        "\n",
        "颜色映射散点图使用 `c` 和 `cmap` 参数，将数值映射到颜色，展示第三个维度的数据。\n",
        "\n",
        "**特点**：\n",
        "- x 轴：第一个变量\n",
        "- y 轴：第二个变量\n",
        "- 颜色：第三个变量（通过颜色映射表示）\n",
        "\n",
        "**基本语法**：\n",
        "```python\n",
        "plt.scatter(x, y, c=values, cmap='viridis')\n",
        "plt.colorbar()  # 显示颜色条\n",
        "```\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例 11：颜色映射散点图\n",
        "# 模拟温度数据：x=时间，y=位置，颜色=温度\n",
        "np.random.seed(42)\n",
        "time = np.arange(0, 24, 0.5)  # 24小时，每30分钟一个点\n",
        "position = np.random.uniform(0, 100, len(time))  # 位置（km）\n",
        "temperature = 20 + 10 * np.sin(2 * np.pi * time / 24) + np.random.randn(len(time)) * 2  # 温度（℃）\n",
        "\n",
        "plt.figure(figsize=(12, 6))\n",
        "scatter = plt.scatter(time, position, c=temperature, cmap='coolwarm', s=100, alpha=0.7, edgecolors='black', linewidths=0.5)\n",
        "plt.colorbar(scatter, label='温度 (℃)')\n",
        "plt.xlabel('时间（小时）', fontsize=12)\n",
        "plt.ylabel('位置（km）', fontsize=12)\n",
        "plt.title('颜色映射散点图：时间 vs 位置（颜色表示温度）', fontsize=14)\n",
        "plt.grid(True, alpha=0.3)\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.3 多组散点图\n",
        "\n",
        "多组散点图用于比较不同组别的数据，通过不同的颜色和标记来区分不同的组。\n",
        "\n",
        "**实现方法**：\n",
        "1. 多次调用 `plt.scatter()`，每次使用不同的颜色和标记\n",
        "2. 使用 `label` 参数添加图例\n",
        "\n",
        "**基本语法**：\n",
        "```python\n",
        "plt.scatter(x1, y1, c='red', marker='o', label='组1')\n",
        "plt.scatter(x2, y2, c='blue', marker='s', label='组2')\n",
        "plt.legend()\n",
        "```\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例 12：多组散点图\n",
        "# 模拟不同产品的销售数据\n",
        "np.random.seed(42)\n",
        "\n",
        "# 产品A\n",
        "x_a = np.random.uniform(0, 10, 30)\n",
        "y_a = x_a * 2 + np.random.randn(30) * 1\n",
        "\n",
        "# 产品B\n",
        "x_b = np.random.uniform(0, 10, 30)\n",
        "y_b = x_b * 1.5 + np.random.randn(30) * 1\n",
        "\n",
        "# 产品C\n",
        "x_c = np.random.uniform(0, 10, 30)\n",
        "y_c = x_c * 3 + np.random.randn(30) * 1\n",
        "\n",
        "plt.figure(figsize=(10, 6))\n",
        "plt.scatter(x_a, y_a, c='red', marker='o', s=100, alpha=0.6, label='产品A', edgecolors='black', linewidths=1)\n",
        "plt.scatter(x_b, y_b, c='blue', marker='s', s=100, alpha=0.6, label='产品B', edgecolors='black', linewidths=1)\n",
        "plt.scatter(x_c, y_c, c='green', marker='^', s=100, alpha=0.6, label='产品C', edgecolors='black', linewidths=1)\n",
        "\n",
        "plt.xlabel('投入（万元）', fontsize=12)\n",
        "plt.ylabel('销售额（万元）', fontsize=12)\n",
        "plt.title('多组散点图：不同产品的投入与销售额关系', fontsize=14)\n",
        "plt.legend(fontsize=11)\n",
        "plt.grid(True, alpha=0.3)\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 3.4 综合案例：多维数据可视化\n",
        "\n",
        "结合气泡图、颜色映射和多组数据，可以创建信息丰富的多维数据可视化。\n",
        "\n",
        "**示例场景**：\n",
        "- x 轴：广告投入\n",
        "- y 轴：销售额\n",
        "- 气泡大小：利润\n",
        "- 颜色：客户满意度\n",
        "- 不同标记：不同产品类别\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# 示例 13：综合案例 - 多维数据可视化\n",
        "np.random.seed(42)\n",
        "\n",
        "# 产品类别A\n",
        "advertising_a = np.random.uniform(20, 80, 20)\n",
        "sales_a = advertising_a * 2.5 + np.random.randn(20) * 15\n",
        "profit_a = np.random.uniform(10, 40, 20)\n",
        "satisfaction_a = np.random.uniform(3, 5, 20)\n",
        "\n",
        "# 产品类别B\n",
        "advertising_b = np.random.uniform(20, 80, 20)\n",
        "sales_b = advertising_b * 2.0 + np.random.randn(20) * 15\n",
        "profit_b = np.random.uniform(10, 40, 20)\n",
        "satisfaction_b = np.random.uniform(3, 5, 20)\n",
        "\n",
        "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6))\n",
        "\n",
        "# 左图：使用不同标记区分类别\n",
        "scatter1 = ax1.scatter(advertising_a, sales_a, s=profit_a*15, c=satisfaction_a, \n",
        "                       cmap='RdYlGn', marker='o', alpha=0.7, edgecolors='black', linewidths=1,\n",
        "                       label='产品类别A')\n",
        "scatter2 = ax1.scatter(advertising_b, sales_b, s=profit_b*15, c=satisfaction_b, \n",
        "                       cmap='RdYlGn', marker='s', alpha=0.7, edgecolors='black', linewidths=1,\n",
        "                       label='产品类别B')\n",
        "ax1.set_xlabel('广告投入（万元）', fontsize=12)\n",
        "ax1.set_ylabel('销售额（万元）', fontsize=12)\n",
        "ax1.set_title('多维数据可视化（标记区分类别）', fontsize=14)\n",
        "ax1.legend(fontsize=11)\n",
        "ax1.grid(True, alpha=0.3)\n",
        "cbar1 = plt.colorbar(scatter1, ax=ax1)\n",
        "cbar1.set_label('客户满意度', fontsize=11)\n",
        "\n",
        "# 右图：使用不同颜色区分类别\n",
        "ax2.scatter(advertising_a, sales_a, s=profit_a*15, c='steelblue', marker='o', \n",
        "            alpha=0.7, edgecolors='black', linewidths=1, label='产品类别A')\n",
        "ax2.scatter(advertising_b, sales_b, s=profit_b*15, c='coral', marker='s', \n",
        "            alpha=0.7, edgecolors='black', linewidths=1, label='产品类别B')\n",
        "ax2.set_xlabel('广告投入（万元）', fontsize=12)\n",
        "ax2.set_ylabel('销售额（万元）', fontsize=12)\n",
        "ax2.set_title('多维数据可视化（颜色区分类别）', fontsize=14)\n",
        "ax2.legend(fontsize=11)\n",
        "ax2.grid(True, alpha=0.3)\n",
        "\n",
        "# 添加说明文本\n",
        "textstr = '气泡大小 = 利润\\n颜色 = 客户满意度'\n",
        "ax2.text(0.02, 0.98, textstr, transform=ax2.transAxes, fontsize=10,\n",
        "         verticalalignment='top', bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.show()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 总结\n",
        "\n",
        "本教程详细介绍了 Matplotlib 散点图的绘制方法，包括：\n",
        "\n",
        "1. **基础散点图**：使用 `plt.scatter(x, y)` 绘制基本散点图\n",
        "2. **散点图定制**：\n",
        "   - 点的大小（`s` 参数）\n",
        "   - 点的颜色（`c` 参数）\n",
        "   - 标记类型（`marker` 参数）\n",
        "   - 透明度（`alpha` 参数）\n",
        "   - 边框颜色（`edgecolors` 参数）\n",
        "   - 颜色映射（`cmap` 参数）\n",
        "\n",
        "3. **高级散点图**：\n",
        "   - 气泡图：使用点的大小表示第三个维度\n",
        "   - 颜色映射散点图：使用颜色表示数值\n",
        "   - 多组散点图：比较不同组别的数据\n",
        "   - 综合案例：多维数据可视化\n",
        "\n",
        "**关键要点**：\n",
        "- `plt.scatter()` 适合绘制独立的点，支持灵活的样式定制\n",
        "- 与 `plt.plot()` 相比，`plt.scatter()` 更适合展示数据分布和关系\n",
        "- 通过组合不同的参数，可以创建信息丰富的多维数据可视化\n",
        "- 气泡图使用 `s` 参数表示第三个维度\n",
        "- 颜色映射散点图使用 `c` 和 `cmap` 参数表示数值\n"
      ]
    }
  ],
  "metadata": {
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 2
}
